#include <openssl/rsa.h>
#include "rsa.h"

#define NID_md5_sha1 114

static void test_rsa_mp_01(void)
{
    RSA *key;
    unsigned char ptext[256];
    unsigned char ctext[256];
    static unsigned char ptext_ex[] = "\x54\x85\x9b\x34\x2c\x49\xea\x2a";
    int plen;
    int num;

    plen = sizeof(ptext_ex) - 1;
    key = RSA_new_c();
    RSA_generate_key_ex_c(key, 1024);
    int size = RSA_size_c(key);
    RSA_check_key_c(key);

    num = RSA_public_encrypt_c(plen, ptext_ex, ctext, key, RSA_PKCS1_PADDING);
    num = RSA_private_decrypt_c(num, ctext, ptext, key, RSA_PKCS1_PADDING);

    RSA_free_c(key);
}

static void test_rsa_mp_02(void)
{
    RSA *key;
    unsigned char ptext[256];
    unsigned char ctext[256];
    static unsigned char ptext_ex[] = "\x54\x85\x9b\x34\x2c\x49\xea\x2a";
    int plen;
    int num;

    plen = sizeof(ptext_ex) - 1;
    key = RSA_new_c();
    RSA_generate_key_ex_c(key, 1024);
    int size = RSA_size_c(key);
    RSA_check_key_c(key);

    num = RSA_private_encrypt_c(plen, ptext_ex, ctext, key, RSA_PKCS1_PADDING);
    num = RSA_public_decrypt_c(num, ctext, ptext, key, RSA_PKCS1_PADDING);

    RSA_free_c(key);
}

static void test_rsa_sign_01()
{
    RSA *key;

    key = RSA_new_c();
    RSA_generate_key_ex_c(key, 1024);
    uint32_t datalen = 36;
    int type = NID_md5_sha1;
    char data[100];
    int i;

    for (i = 0; i < 100; i++) {
        data[i] = i + 1;
    }

    int size = RSA_size_c(key);
    char *sigret = malloc(size);

    int ret = RSA_sign_c(type, data, datalen, sigret, &size, key);
    if (ret == -1) {
        goto end;
    }

    ret = RSA_verify_c(type, data, datalen, sigret, size, key);
    if (ret == -1) {
        goto end;
    }

end:
    free(sigret);
    RSA_free_c(key);
}

static void test_rsa_PEM_rw_01()
{
    RSA *key;

    key = RSA_new_c();
    RSA_generate_key_ex_c(key, 1024);
    uint32_t datalen = 36;
    int type = NID_md5_sha1;
    char data[100];
    int i;

    PEM_write_bio_RSAPrivateKey_c("build/rsa_test_pri.pem", key, 1);
    PEM_write_bio_RSA_PUBKEY_c("build/rsa_test_pub.pem", key, 1, 1);

    PEM_read_bio_RSAPrivateKey_c("build/rsa_test_pri.pem", 1);
    PEM_read_bio_RSA_PUBKEY_c("build/rsa_test_pub.pem", 1, 1);

    RSA_free_c(key);
}

static void test_rsa_PEM_rw_02()
{
    RSA *key;

    key = RSA_new_c();
    RSA_generate_key_ex_c(key, 1024);
    uint32_t datalen = 36;
    int type = NID_md5_sha1;
    char data[100];
    int i;

    PEM_write_bio_RSAPrivateKey_c("build/rsa_test_pri.pem", key, 1);
    PEM_write_bio_RSA_PUBKEY_c("build/rsa_test_pub.pem", key, 1, 0);

    PEM_read_bio_RSAPrivateKey_c("build/rsa_test_pri.pem", 1);
    PEM_read_bio_RSA_PUBKEY_c("build/rsa_test_pub.pem", 1, 0);

    RSA_free_c(key);
}

void setup_rsa_tests(void)
{
    test_rsa_mp_01();
    test_rsa_mp_02();
    test_rsa_sign_01();
    test_rsa_PEM_rw_01();
    test_rsa_PEM_rw_02();
}